package com.zhoug.aop.aspect;

import android.app.Activity;
import android.content.Context;

import com.zhoug.aop.AopLib;
import com.zhoug.aop.ZLog;
import com.zhoug.aop.annotation.NeedLogin;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;

import androidx.fragment.app.Fragment;

/**登录状态拦截
 * @Author 35574
 * @Date 2020/7/1
 * @Description
 */
@Aspect
public class NeedLoginAspect {
    private static final String TAG = ">>>NeedLoginAspect";
    private static final String POINTCUT_ON_ANNOTATION = "execution(@com.zhoug.aop.annotation.NeedLogin * *(..))";

    public NeedLoginAspect(){
        ZLog.d(TAG, "NeedLoginAspect:");
    }

    //切入点
    @Pointcut(POINTCUT_ON_ANNOTATION)
    public void onAnnotation(){
    }

    @Around("onAnnotation()")
    public void aroundLogin(ProceedingJoinPoint joinPoint) throws Throwable {
        ZLog.d(TAG, "-----need login:");
        try {
            if(AopLib.getLoginFilter()==null){
                ZLog.e(TAG, "NeedLoginAspect:AopLib.getNeedLoginListener()==null");
                joinPoint.proceed();
                return;
            }else{
                if(AopLib.getLoginFilter().isLogin()){
                    joinPoint.proceed();
                    return;
                }
            }
            //只能注释在方法上
            Signature signature = joinPoint.getSignature();
            if (!(signature instanceof MethodSignature)){
                ZLog.e(TAG, "method is no MethodSignature, so proceed it");
                joinPoint.proceed();
                return;
            }

            MethodSignature methodSignature = (MethodSignature) signature;
            ZLog.d(TAG, "aroundLogin:methodSignature="+methodSignature);
            Method method = methodSignature.getMethod();
            ZLog.d(TAG, "processJoinPoint:method="+method);//
            boolean isNeedLoginAnnotation = method.isAnnotationPresent(NeedLogin.class);
            ZLog.d(TAG, "processJoinPoint:isHasLimitAnnotation="+isNeedLoginAnnotation);
            String methodName = method.getName();
            //被NeedLogin注释
            if (isNeedLoginAnnotation){
                NeedLogin needLogin = method.getAnnotation(NeedLogin.class);
                handlerWithType(needLogin,joinPoint);
            }else{
                joinPoint.proceed();
            }


        }catch (Exception e){
            e.printStackTrace();
            ZLog.d(TAG, e.getMessage());
            joinPoint.proceed();
        }
    }

    /**
     * 处理未登录时事件
     * @param needLogin
     * @param joinPoint
     */
    private void handlerWithType(NeedLogin needLogin, ProceedingJoinPoint joinPoint){
      switch ( needLogin.value()){
          case NeedLogin.SHOW_TOAST:
              ZLog.d(TAG,"弹出吐司提示登录");
              if(AopLib.getLoginFilter()!=null){
                  AopLib.getLoginFilter().showToast(needLogin.tipToast());
              }
              break;
          case NeedLogin.SHOW_DIALOG:
              ZLog.d(TAG,"展示Dialog提示登录");
              if(AopLib.getLoginFilter()!=null){
                  AopLib.getLoginFilter().showDialog(getContext(joinPoint),needLogin.tipDialog());
              }
              break;
          case NeedLogin.TO_LOGIN:
              ZLog.d(TAG,"登录,跳转到登录页");
              if(AopLib.getLoginFilter()!=null){
                  AopLib.getLoginFilter().toLogin(getContext(joinPoint));
              }
              break;
          case NeedLogin.NO_RESPONSE:
              ZLog.d(TAG,"没有响应");
              break;
      }
    }

    private Context getContext(ProceedingJoinPoint joinPoint){
        if(joinPoint!=null){
            Object aThis = joinPoint.getThis();
            if(aThis instanceof Activity){
                return (Activity) aThis;
            }else if(aThis instanceof Fragment){
                return ((Fragment)aThis).getContext();
            }else if(aThis instanceof android.app.Fragment){
                return ((android.app.Fragment)aThis).getActivity();
            }
        }
        return null;
    }
}
